using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.SessionState;
using System.Web.UI.WebControls;
using Edge.Common.ControlFlow;
using Edge.Common.Utils;
using Edge.Common.Web.DataSourceAdapters;
using Edge.Common.ControlFlow;
using Edge.Common.Utils;
using Edge.Common.Web.DataSourceAdapters;

namespace Edge.Common.Web.Controls.Grid
{
    public class FetchStateRestorer
    {
        private GridView grid;
        private string sortExpression = string.Empty;
        private SortDirection sortDirection = SortDirection.Ascending;

        [Serializable]
        protected class StoredData
        {
            private string sortExpression;
            private SortDirection sortDirection = SortDirection.Ascending;
            private int pageIndex;
            private IFilteringState filteringState = null;

            public StoredData()
            {
            }

            public StoredData(string sortExpression)
            {
                this.sortExpression = sortExpression;
            }

            public string SortExpression
            {
                get { return sortExpression; }
                set { sortExpression = value; }
            }

            public SortDirection SortDirection
            {
                get { return sortDirection; }
                set { sortDirection = value; }
            }


            public int PageIndex
            {
                get { return pageIndex; }
                set { pageIndex = value; }
            }

            public IFilteringState FilteringState
            {
                get { return filteringState; }
                set { filteringState = value; }
            }
        }

        public FetchStateRestorer(GridView grid)
        {
            if (grid == null)
                throw new ArgumentException("grid");

            this.grid = grid;

            object dataSource = grid.DataSource;
            BaseDataSource adaptedDataSource = dataSource as BaseDataSource;
            if (adaptedDataSource != null)
            {
                BaseDataSourceView view = (BaseDataSourceView)adaptedDataSource.GetView(BaseDataSource.DEFAULT);
                view.SelectExecuted += View_OnSelectExecuted;
                view.SelectPreExecute += View_OnSelectPreExecute;
            }
        }

        public FetchStateRestorer(GridView grid, string sortExpression, SortDirection sortDirection)
        {
            if (grid == null)
                throw new ArgumentException("grid");

            this.grid = grid;

            object dataSource = grid.DataSource;
            BaseDataSource adaptedDataSource = dataSource as BaseDataSource;
            if (adaptedDataSource != null)
            {
                BaseDataSourceView view = (BaseDataSourceView)adaptedDataSource.GetView(BaseDataSource.DEFAULT);
                view.SelectExecuted += View_OnSelectExecuted;
                view.SelectPreExecute += View_OnSelectPreExecute;

                this.sortExpression = sortExpression;
                this.sortDirection = sortDirection;
            }
        }

        private void View_OnSelectPreExecute(object sender, BaseDataSourceView.PreSelectEventArgs e)
        {
            if (StringUtils.IsBlankOrNull(e.FetchOptions.SortExpression))
            {
                if (!StringUtils.IsBlankOrNull(Stored.SortExpression))
                {
                    e.FetchOptions.SortExpression = Stored.SortExpression;
                    e.FetchOptions.SortDirection = Stored.SortDirection;
                }

                if (grid.AllowPaging && Stored.FilteringState != null)
                {
                    IFilteringStateProvider filteringStateProvider = grid.DataSource as IFilteringStateProvider;
                    Assert.CheckNotNull(filteringStateProvider);
                    if (Stored.FilteringState.Equals(filteringStateProvider.GetFilteringState()))
                    {
                        grid.PageIndex = Stored.PageIndex;
                        e.FetchOptions.FirstResult = grid.PageIndex * grid.PageSize;
                        e.FetchOptions.MaxResults = grid.PageSize;
                    }
                }
            }
        }


        private void View_OnSelectExecuted(object sender, BaseDataSourceView.SelectedEventArgs e)
        {
            Stored.SortExpression = e.SortExpression;
            Stored.SortDirection = e.SortDirection == SortDirection.Ascending ?
                SortDirection.Ascending : SortDirection.Descending;

            Stored.PageIndex = grid.PageIndex;

            if (grid.AllowPaging)
            {
                IFilteringStateProvider filteringStateProvider = grid.DataSource as IFilteringStateProvider;
                if (filteringStateProvider != null)
                {
                    IFilteringState state = filteringStateProvider.GetFilteringState();
                    Stored.FilteringState = state;
                }
            }
        }

        protected StoredData Stored
        {
            get
            {
                StoredData ret = (StoredData)Session[DataKey];
                if (ret == null)
                {
                    ret = CreatebyDefault();
                    Session[DataKey] = ret;
                }
                return ret;
            }
            set
            {
                Session[DataKey] = value;
            }
        }

        protected StoredData CreatebyDefault()
        {
            if (StringUtils.IsBlankOrNull(sortExpression))
            {
                string _sortExpression = string.Empty;

                foreach (DataControlField column in grid.Columns)
                {
                    if (!StringUtils.IsBlankOrNull(column.SortExpression))
                    {
                        _sortExpression = column.SortExpression;
                        break;
                    }
                }
                return new StoredData(_sortExpression);
            }
            else
            {
                StoredData ret = new StoredData(sortExpression.Trim());
                ret.SortDirection = sortDirection;

                return ret;
            }
        }

        protected HttpSessionState Session
        {
            get
            {
                HttpContext context = HttpContext.Current;
                if (context == null)
                    throw new InvalidOperationException();

                return context.Session;
            }
        }

        string DataKey
        {
            get
            {
                return "FetchStateRestorer_KEY_for_control_" + grid.Page.GetType().Name + grid.ClientID;
            }
        }

    }
}
